import patchVnode from "./patchVnode";
import createElement from "./createElement";
// 判断是否是同一个虚拟节点
function checkSameVnode(a, b) {
  return a.sel === b.sel && a.key === b.key;
}
export default function updateChildren(parentElm, oldCh, newCh) {
  // 旧前
  let oldStartIdx = 0;
  // 新前
  let newStartIdx = 0;
  // 旧后
  let oldEndIdx = oldCh.length - 1;
  // 新后
  let newEndIdx = newCh.length - 1;
  // 旧前节点
  let oldStartVnode = oldCh[oldStartIdx];
  // 新前节点
  let newStartVnode = newCh[newStartIdx];
  // 旧后节点
  let oldEndVnode = oldCh[oldEndIdx];
  // 新后节点
  let newEndVnode = newCh[newEndIdx];
  // 缓存没有命中的内容
  let keyMap = null;

  while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
    // 跳过处理过的内容
    if (!oldStartVnode) {
      oldStartVnode = oldCh[++oldStartIdx];
    } else if (!newStartVnode) {
      newStartVnode = oldCh[++newStartIdx];
    } else if (!oldEndVnode) {
      oldEndVnode = oldCh[--oldEndIdx];
    } else if (!newEndVnode) {
      newEndVnode = oldCh[--newEndIdx];
    }
    // 命中逻辑
    if (checkSameVnode(oldStartVnode, newStartVnode)) {
      console.log("旧前 <> 新前");
      // 旧前 <> 新前
      patchVnode(oldStartVnode, newStartVnode);
      oldStartVnode = oldCh[++oldStartIdx];
      newStartVnode = newCh[++newStartIdx];
    } else if (checkSameVnode(newEndVnode, oldEndVnode)) {
      console.log("新后 <> 旧后");
      // 新后 <> 旧后
      patchVnode(oldEndVnode, newEndVnode);
      newEndVnode = newCh[--newEndIdx];
      oldEndVnode = oldCh[--oldEndIdx];
    } else if (checkSameVnode(newEndVnode, oldStartVnode)) {
      console.log("新后 <> 旧前");
      // 新后 <> 旧前
      patchVnode(oldStartVnode, newEndVnode);
      // 移动位置 (移动新前指向的这个节点到老节点的旧后的后边)
      parentElm.insertBefore(oldStartVnode.elm, oldEndVnode.elm.nextSibling);
      newEndVnode = newCh[--newEndIdx];
      oldStartVnode = oldCh[++oldStartIdx];
    } else if (checkSameVnode(newStartVnode, oldEndVnode)) {
      console.log("新前 <> 旧后");
      // 新前 <> 旧后
      patchVnode(oldEndVnode, newStartVnode);
      // 移动位置 (移动新前指向的这个节点到老节点的旧前的前边)
      parentElm.insertBefore(oldEndVnode.elm, oldStartVnode.elm);
      newStartVnode = newCh[++newStartIdx];
      oldEndVnode = oldCh[--oldEndIdx];
    } else {
      // insert
      console.log("没有命中");
      if (!keyMap) {
        keyMap = {};
        for (let i = oldStartIdx; i <= oldEndIdx; i++) {
          let key = oldCh[i].key;
          if (key !== undefined) {
            keyMap[key] = i;
          }
        }
      }
      let idxInOld = keyMap[newStartVnode.key];
      if (idxInOld === undefined) {
        // 全新的项
        parentElm.insertBefore(createElement(newStartVnode), oldStartVnode.elm);
        // newCh[newStartIdx] = undefined;
      } else {
        // 移动
        const elmToMove = oldCh[idxInOld];
        patchVnode(elmToMove, newStartVnode);
        // 处理完成后标记为undefined
        oldCh[idxInOld] = undefined;
        parentElm.insertBefore(elmToMove, oldStartVnode.elm);
      }
      newStartVnode = newCh[++newStartIdx];
    }
  }

  if (newStartIdx <= newEndIdx) {
    // 循环结束了, start还是比end的小
    console.log("还剩余未渲染的节点");
    let before = newCh[newEndIdx + 1] ? newCh[newEndIdx + 1].elm : null;
    for (let i = newStartIdx; i <= newEndIdx; i++) {
      parentElm.insertBefore(createElement(newCh[i]), before);
    }
  } else if (oldStartIdx <= oldEndIdx) {
    // 不需要的节点还存在
    console.log("不需要的节点还存在");
    // 循环删除
    for (let i = oldStartIdx; i <= oldEndIdx; i++) {
      parentElm.removeChild(oldCh[i].elm);
    }
  }
}
